#include "CF_Core.h"

CCF_SkyBox::CCF_SkyBox(void)
{
}

CCF_SkyBox::~CCF_SkyBox(void)
{
}

BOOL CCF_SkyBox::Initialize( LPDIRECT3DDEVICE9 device, const LPWSTR filenames[], float size )
{
  m_device = device;
  WCHAR fullpath[ MAX_PATH ];

  for(int i = 0; i < 6; ++i)
  {
    GetFullPathName( filenames[ i ], MAX_PATH, fullpath, NULL );
    if( FAILED( D3DXCreateTextureFromFile( device, 
      fullpath, &this->m_textures[i]) ))
      return FALSE;
  }	

  if( FAILED( device->CreateVertexBuffer( SKY_VERTEX_COUNT*sizeof(SCF_SkyVertex), 
    D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &this->m_vertexBuffer, 0)))
    return FALSE;

  SCF_SkyVertex* pVertices;
  this->m_vertexBuffer->Lock(0, 0, (void**)&pVertices, 0);

  // right
  pVertices[0] = SCF_SkyVertex( size, -size,  size, 0.0f, 1.0f);
  pVertices[1] = SCF_SkyVertex( size,  size,  size, 0.0f, 0.0f);
  pVertices[2] = SCF_SkyVertex( size,  size, -size, 1.0f, 0.0f);
  pVertices[3] = SCF_SkyVertex( size, -size, -size, 1.0f, 1.0f);

  // left
  pVertices[4] = SCF_SkyVertex(-size, -size, -size, 0.0f, 1.0f);
  pVertices[5] = SCF_SkyVertex(-size,  size, -size, 0.0f, 0.0f);
  pVertices[6] = SCF_SkyVertex(-size,  size,  size, 1.0f, 0.0f);
  pVertices[7] = SCF_SkyVertex(-size, -size,  size, 1.0f, 1.0f);

  // top
  pVertices[8]  = SCF_SkyVertex(-size,  size,  size, 0.0f, 1.0f);
  pVertices[9]  = SCF_SkyVertex(-size,  size, -size, 0.0f, 0.0f); 
  pVertices[10] = SCF_SkyVertex( size,  size, -size, 1.0f, 0.0f);
  pVertices[11] = SCF_SkyVertex( size,  size,  size, 1.0f, 1.0f);

  // bottom
  pVertices[12] = SCF_SkyVertex(-size, -size, -size, 0.0f, 1.0f);
  pVertices[13] = SCF_SkyVertex(-size, -size,  size, 0.0f, 0.0f);
  pVertices[14] = SCF_SkyVertex( size, -size,  size, 1.0f, 0.0f);
  pVertices[15] = SCF_SkyVertex( size, -size, -size, 1.0f, 1.0f);

  // back
  pVertices[16] = SCF_SkyVertex(-size, -size,  size, 0.0f, 1.0f);
  pVertices[17] = SCF_SkyVertex(-size,  size,  size, 0.0f, 0.0f);
  pVertices[18] = SCF_SkyVertex( size,  size,  size, 1.0f, 0.0f);
  pVertices[19] = SCF_SkyVertex( size, -size,  size, 1.0f, 1.0f);

  // front
  pVertices[20] = SCF_SkyVertex( size, -size, -size, 0.0f, 1.0f);
  pVertices[21] = SCF_SkyVertex( size,  size, -size, 0.0f, 0.0f);
  pVertices[22] = SCF_SkyVertex(-size,  size, -size, 1.0f, 0.0f);
  pVertices[23] = SCF_SkyVertex(-size, -size, -size, 1.0f, 1.0f);

  this->m_vertexBuffer->Unlock();

  if( device->CreateIndexBuffer( SKY_INDEX_COUNT*sizeof(WORD), D3DUSAGE_WRITEONLY,
    D3DFMT_INDEX16, D3DPOOL_DEFAULT, &this->m_indexBuffer, 0))
    return FALSE;

  WORD aIndices[] = {0,1,2, 0,2,3, 4,5,6, 4,6,7, 8,9,10, 8,10,11, 
    12,13,14, 12,14,15, 16,17,18, 16,18,19, 20,21,22, 20,22,23 };
  WORD* pIndices;

  this->m_indexBuffer->Lock(0, 0, (void**)&pIndices, 0);
  memcpy( pIndices, aIndices, sizeof(aIndices) );
  this->m_indexBuffer->Unlock();

  return TRUE;
}

void CCF_SkyBox::Render( CCF_Camera* camera )
{
  m_device->SetRenderState(D3DRS_LIGHTING, false);
  m_device->SetRenderState(D3DRS_ZWRITEENABLE, false);
  m_device->SetRenderState(D3DRS_ZENABLE, false);
  m_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
  m_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);

  D3DXMATRIX transform;
  
 
  D3DXMatrixTranslation(&transform, camera->GetPosition().x, camera->GetPosition().y, camera->GetPosition().z);
  m_device->SetTransform(D3DTS_WORLD, &transform);

  m_device->SetFVF( SKY_VERTEX_FVF );
  m_device->SetStreamSource(0, this->m_vertexBuffer, 0, sizeof(SCF_SkyVertex));
  m_device->SetIndices(this->m_indexBuffer);

  for(int i = 0; i < 6; ++i)
  {
    m_device->SetTexture(0, this->m_textures[i]);
    m_device->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, i*4, 4, i*6, 2 );
  }

  D3DXMatrixIdentity(&transform);
  m_device->SetTransform(D3DTS_WORLD, &transform);

  m_device->SetRenderState(D3DRS_LIGHTING, true);
  m_device->SetRenderState(D3DRS_ZWRITEENABLE, true);
  m_device->SetRenderState(D3DRS_ZENABLE, true);
  m_device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP);
  m_device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP);
}
